package com.steve.summary.two_PC;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @Author: STEVE
 * @Description: 协调者
 * @since: 2025-05-21
 */
public class Coordinator {

    private List<Participant> participants = new ArrayList<>();

    public void addParticipant(Participant participant) {
        participants.add(participant);
    }

    /**
     * 执行两阶段提交
     *
     * @param txId       事务ID
     * @param operations 参与者操作映射
     * @return true/false 表示事务是否成功
     */
    public boolean execute2PC(String txId, Map<Participant, Integer> operations) {
        // ----------- Phase 1: Prepare -----------
        List<Participant> preparedParticipants = new ArrayList<>();
        for (Map.Entry<Participant, Integer> entry : operations.entrySet()) {
            Participant p = entry.getKey();
            int amount = entry.getValue();
            if (!p.prepare(txId, amount)) {
                rollbackAll(txId, preparedParticipants);
                return false;
            }
            preparedParticipants.add(p);
        }

        // ----------- Phase 2: Commit -----------
        for (Map.Entry<Participant, Integer> entry : operations.entrySet()) {
            Participant p = entry.getKey();
            int amount = entry.getValue();
            if (!p.commit(txId, amount)) {
                System.out.println("[ERROR] Partial commit failed!");
                return false; // 部分提交失败（需人工干预）
            }
        }

        System.out.println("[Coordinator] TX " + txId + " successfully committed!");
        return true;
    }

    /**
     * 回滚所有已准备的参与者
     */
    private void rollbackAll(String txId, List<Participant> participants) {
        for (Participant p : participants) {
            p.rollback(txId);
        }
    }

}
